home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / mac-perl / gs_102st.bin / GUSI / GUSIINETTest.c / GUSIINETTest.c
Encoding:
C/C++ Source or Header  |  1992-09-15  |  6.2 KB  |  319 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. File        :    GUSI                -    Grand Unified Socket Interface
  3. File        :    GUSIINETTest    -    Test unix domain sockets
  4. Author    :    Matthias Neeracher <neeri@iis.ethz.ch>
  5. Started    :    02Sep92
  6. Modified    :    08Sep92    MN    First attempt
  7.                 08Sep92    MN    Factor out common socket routines
  8.                 14Sep92    MN    Misinterpreted hostent structure
  9. Last        :    14Sep92
  10. *********************************************************************/
  11.  
  12. #include <GUSI.h>
  13. #include <GUSITest.h>
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <stdlib.h>
  17. #include <errno.h>
  18. #include <string.h>
  19.  
  20. #include "Events.h"
  21.  
  22. extern int GUSIDefaultSpin(spin_msg, long);
  23.  
  24. char    addrstr[100];
  25.  
  26. void Socket(char ch1, char, const char *)
  27. {
  28.     sock    =    socket(AF_INET, (ch1 == 's') ? SOCK_STREAM : SOCK_DGRAM, 0);
  29.     
  30.     if (sock == -1)    {
  31.         printf("# socket() returned error %s\n", Explain());
  32.         Where();
  33.     }
  34. }
  35.  
  36. void Bind(char ch1, char ch2, const char * cmd)
  37. {
  38.     int                        len;
  39.     struct sockaddr_in    addr;
  40.  
  41.     if (sock == -1)    {
  42.         printf("# socket is not open\n");
  43.         Where();
  44.         
  45.         return;
  46.     }
  47.  
  48.     if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
  49.         addr.sin_addr            =    inet_addr(addrstr);
  50.         addr.sin_family        =    AF_INET;
  51.         len                        =    sizeof(struct sockaddr_in);
  52.     } else {
  53.         Usage(ch1, ch2);
  54.         return;
  55.     }
  56.     
  57.     if (bind(sock, &addr, len))    {
  58.         printf(
  59.             "bind(%s:%d) returned error %s\n", 
  60.             inet_ntoa(addr.sin_addr),
  61.             addr.sin_port, 
  62.             Explain());
  63.             
  64.         Where();
  65.     }
  66. }
  67.  
  68. void Accept(char, char, const char *)
  69. {
  70.     int                        len;
  71.     struct sockaddr_in    addr;
  72.  
  73.     if (sock == -1)    {
  74.         printf("# socket is not open\n");
  75.         Where();
  76.         
  77.         return;
  78.     }
  79.     if (accsock != -1)    {
  80.         printf("# can't accept more than one connection\n");
  81.         Where();
  82.         
  83.         return;
  84.     }
  85.  
  86.     len    =    sizeof(struct sockaddr_in);
  87.     sock    =    accept(accsock = sock, &addr, &len);
  88.     
  89.     if (sock < 0)    {
  90.         printf("# accept() returned error %s\n", Explain());
  91.         sock        =    accsock;
  92.         accsock    =    -1;
  93.     } else {
  94.         printf(
  95.             "# accepted connection from %s port %d\n", 
  96.             inet_ntoa(addr.sin_addr), 
  97.             addr.sin_port);
  98.     }
  99.     
  100.     Where();
  101. }
  102.     
  103. void Connect(char ch1, char ch2, const char * cmd)
  104. {
  105.     int                        len;
  106.     struct sockaddr_in    addr;
  107.  
  108.     if (sock == -1)    {
  109.         printf("# socket is not open\n");
  110.         Where();
  111.         
  112.         return;
  113.     }
  114.     
  115.     if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
  116.         addr.sin_addr            =    inet_addr(addrstr);
  117.         addr.sin_family        =    AF_INET;
  118.         len                        =    sizeof(struct sockaddr_in);
  119.     } else {
  120.         Usage(ch1, ch2);
  121.         return;
  122.     }
  123.  
  124.     if (connect(sock, &addr, len))    {
  125.         printf(
  126.             "connect(%s:%d) returned error %s\n", 
  127.             inet_ntoa(addr.sin_addr),
  128.             addr.sin_port, 
  129.             Explain());
  130.         Where();
  131.     }
  132. }    
  133.  
  134. int ReadWhileUCan()
  135. {
  136.     int                res;
  137.     char *            outline;
  138.     fd_set            rdfds;
  139.     fd_set            exfds;
  140.     struct timeval    delay;
  141.     char                 out[500];
  142.  
  143.     for (;;) {
  144.         FD_ZERO(&rdfds);
  145.         FD_ZERO(&exfds);
  146.         
  147.         FD_SET(sock, &rdfds);
  148.         FD_SET(sock, &exfds);
  149.         
  150.         delay.tv_sec    =    1;
  151.         delay.tv_usec    =    0;
  152.         
  153.         res = select(sock+1, &rdfds, nil, &exfds, &delay);
  154.         
  155.         if (res < 0)    {
  156.             printf("# select() returned error %s\n", Explain());
  157.             
  158.             return -1;
  159.         } else if (!res)
  160.             return 0;
  161.         else if (res && FD_ISSET(sock, &exfds)) {
  162.             printf("# select() returned an exception\n");
  163.             
  164.             return -1;
  165.         } else if (res && FD_ISSET(sock, &rdfds)) {
  166.             res = read(sock, out, 500);
  167.             
  168.             if (res < 0) {
  169.                 printf("# read() returned error %s\n", Explain());
  170.             
  171.                 return -1;
  172.             }
  173.             
  174.             out[res] = 0;
  175.             
  176.             for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
  177.                 printf("%s\n", outline);
  178.         }
  179.     }
  180. }
  181.  
  182. void Telnet(char, char, const char *)
  183. {
  184.     int                len;
  185.     int                 part;
  186.     int                res;
  187.     char *            line;
  188.     char *            outline;
  189.     fd_set            rdfds;
  190.     fd_set            wrfds;
  191.     fd_set            exfds;
  192.     struct timeval    delay;
  193.     char                 in[100];
  194.     char                 out[500];
  195.     
  196.     if (sock == -1)    {
  197.         printf("# socket is not open\n");
  198.         Where();
  199.             
  200.         return;
  201.     }
  202.  
  203.     printf("# Entering Poor Man's Telnet mode\n");
  204.     
  205.     for (;;) {
  206.         if (ReadWhileUCan())
  207.             break;
  208.         
  209.         Prompt();
  210.         
  211.         if (!fgets(in, 100, input))
  212.             break;
  213.             
  214.         ++inputline;
  215.         
  216.         if (!strcmp(in, ".\n"))
  217.             break;
  218.         
  219.         if (!strcmp(in, "?\n"))
  220.             continue;
  221.  
  222.         len             = strlen(in);
  223.         in[len++]    = '\r';
  224.         in[len]        = 0;
  225.         
  226.         for (line = in; len; len -= part, line += part) {        
  227.             part = 0;
  228.  
  229.             FD_ZERO(&rdfds);
  230.             FD_ZERO(&wrfds);
  231.             FD_ZERO(&exfds);
  232.             
  233.             FD_SET(sock, &rdfds);
  234.             FD_SET(sock, &wrfds);
  235.             FD_SET(sock, &exfds);
  236.             
  237.             delay.tv_sec    =    10;
  238.             delay.tv_usec    =    0;
  239.             
  240.             res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
  241.             
  242.             if (res < 0)    {
  243.                 printf("# select() returned error %s\n", Explain());
  244.                 
  245.                 return;
  246.             } else if (!res) {
  247.                 printf("# select() timed out\n");
  248.                 
  249.                 return;
  250.             } else if (FD_ISSET(sock, &exfds)) {
  251.                 printf("# select() returned an exception\n");
  252.                 
  253.                 return;
  254.             }
  255.             
  256.             if (FD_ISSET(sock, &rdfds)) {
  257.                 res = read(sock, out, 500);
  258.                 
  259.                 if (res < 0) {
  260.                     printf("# read() returned error %s\n", Explain());
  261.                 
  262.                     return;
  263.                 }
  264.                 
  265.                 out[res] = 0;
  266.                 
  267.                 for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
  268.                     printf("%s\n", outline);
  269.             } else if (FD_ISSET(sock, &wrfds)) {
  270.                 res = write(sock, line, len);
  271.             
  272.                 if (res < 0) {
  273.                     line[strlen(line) - 2] = 0;
  274.                     printf("# write(\"%s\") returned error %s\n", line, Explain());
  275.                 
  276.                     return;
  277.                 }
  278.                 
  279.                 part = res;
  280.             }
  281.         }
  282.     }
  283.     
  284.     printf("# Leaving Poor Man's Telnet mode\n");
  285. }
  286.  
  287. void N2Addr(char ch1, char ch2, const char * cmd)
  288. {
  289.     struct in_addr        addr;
  290.     struct hostent *    ent;
  291.     
  292.     if (sscanf(cmd, "%s", addrstr) == 1)
  293.         if (ent = gethostbyname(addrstr)) {
  294.             memcpy(&addr, ent->h_addr, sizeof(struct in_addr));
  295.             printf("# gethostbyname(%s) returned %s\n", addrstr, inet_ntoa(addr));
  296.         } else
  297.             printf("# gethostbyname(%s) failed.\n", addrstr);
  298.     else
  299.         Usage(ch1, ch2);
  300. }
  301.  
  302. main(int argc, char ** argv)
  303. {
  304.     printf("GUSIINETTest        MN 14Sep92\n\n");
  305.  
  306.     COMMAND('s', 's', Socket,  "",                 "Create a stream socket");
  307.     COMMAND('d', 's', Socket,  "",                 "Create a datagram socket");
  308.     COMMAND('b', 'd', Bind,      "addr port",     "Bind to address");
  309.     COMMAND('c', 'o', Connect, "addr port",     "Connect to address");
  310.     COMMAND('a', 'c', Accept,  "",                 "Accept a connection");
  311.     COMMAND('t', 'n', Telnet,  "",                "Play telnet");
  312.     COMMAND('n', 'a', N2Addr,    "addr",            "Convert name to address");
  313.     
  314.     AddSocketCommands();
  315.     
  316.     GUSISetEvents(GUSISIOWEvents);
  317.     RunTest(argc, argv);
  318.     CleanupSockets();
  319. }